package utils;

import model.LockInfo;


public class Granularidade {
	public static boolean [][] matrizCompatibilidade;
	public static void initialize(){
		matrizCompatibilidade = new boolean[6][6];
		//READ LOCK
		matrizCompatibilidade[LockInfo.RL][LockInfo.RL] = true;
		matrizCompatibilidade[LockInfo.RL][LockInfo.WL] = false;
		matrizCompatibilidade[LockInfo.RL][LockInfo.UL] = false;
		matrizCompatibilidade[LockInfo.RL][LockInfo.IRL] = true;
		matrizCompatibilidade[LockInfo.RL][LockInfo.IWL] = false;
		matrizCompatibilidade[LockInfo.RL][LockInfo.IUL] = false;
		//WRITELOCK
		matrizCompatibilidade[LockInfo.WL][LockInfo.RL] = false;
		matrizCompatibilidade[LockInfo.WL][LockInfo.WL] = false;
		matrizCompatibilidade[LockInfo.WL][LockInfo.UL] = false;
		matrizCompatibilidade[LockInfo.WL][LockInfo.IRL] = false;
		matrizCompatibilidade[LockInfo.WL][LockInfo.IWL] = false;
		matrizCompatibilidade[LockInfo.WL][LockInfo.IUL] = false;
		//UPDATELOCK
		matrizCompatibilidade[LockInfo.UL][LockInfo.RL] = true;
		matrizCompatibilidade[LockInfo.UL][LockInfo.WL] = false;
		matrizCompatibilidade[LockInfo.UL][LockInfo.UL] = false;
		matrizCompatibilidade[LockInfo.UL][LockInfo.IRL] = true;
		matrizCompatibilidade[LockInfo.UL][LockInfo.IWL] = false;
		matrizCompatibilidade[LockInfo.UL][LockInfo.IUL] = false;
		//INTENCIONAL READLOCK
		matrizCompatibilidade[LockInfo.IRL][LockInfo.RL] = true;
		matrizCompatibilidade[LockInfo.IRL][LockInfo.WL] = false;
		matrizCompatibilidade[LockInfo.IRL][LockInfo.UL] = false;
		matrizCompatibilidade[LockInfo.IRL][LockInfo.IRL] = true;
		matrizCompatibilidade[LockInfo.IRL][LockInfo.IWL] = true;
		matrizCompatibilidade[LockInfo.IRL][LockInfo.IUL] = true;
		//INTENCIONAL WRITELOCK
		matrizCompatibilidade[LockInfo.IWL][LockInfo.RL] = false;
		matrizCompatibilidade[LockInfo.IWL][LockInfo.WL] = false;
		matrizCompatibilidade[LockInfo.IWL][LockInfo.UL] = false;
		matrizCompatibilidade[LockInfo.IWL][LockInfo.IRL] = true;
		matrizCompatibilidade[LockInfo.IWL][LockInfo.IWL] = true;
		matrizCompatibilidade[LockInfo.IWL][LockInfo.IUL] = true;
		//INTENCIONAL UPDATELOCK
		matrizCompatibilidade[LockInfo.IUL][LockInfo.RL] = true;
		matrizCompatibilidade[LockInfo.IUL][LockInfo.WL] = false;
		matrizCompatibilidade[LockInfo.IUL][LockInfo.UL] = false;
		matrizCompatibilidade[LockInfo.IUL][LockInfo.IRL] = true;
		matrizCompatibilidade[LockInfo.IUL][LockInfo.IWL] = true;
		matrizCompatibilidade[LockInfo.IUL][LockInfo.IUL] = true;
	}
	
	public static boolean isLockCompatible(int existLock, int wantLock){
		return matrizCompatibilidade[existLock][wantLock];
	}

	public static void imprimeTabela() {
		System.out.printf("%3s|","");
		for (int i = 0; i < matrizCompatibilidade.length; i++) {
			System.out.printf("%4s |",getLockName(i));
		}
		System.out.println();
		for (int i = 0; i < matrizCompatibilidade.length; i++) {
			System.out.printf("%3s|",getLockName(i));
			for (int j = 0; j < matrizCompatibilidade[i].length; j++) {
				System.out.printf("%-5s|",(matrizCompatibilidade[i][j]?"+":"-"));
			}
			System.out.println();
		}
	}
	
	private static String getLockName(int lock){
		switch (lock) {
		case LockInfo.RL:
			return "RL";
		case LockInfo.WL:
			return "WL";
		case LockInfo.UL:
			return "UL";
		case LockInfo.IRL:
			return "IRL";
		case LockInfo.IWL:
			return "IWL";
		case LockInfo.IUL:
			return "IUL";
		default:
			return "";
		}
	}
}
